package cpr.data;

import java.util.Iterator;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import cpr.context.SolveContext;

public class SolveBestRules {
	private boolean doSelfCheck = true;
	SortedSet bestRules;
    SolveBestRulesComparator comparator;
    SolveContext ctx;
    public SolveBestRules(SolveContext ctx) {
        comparator = new SolveBestRulesComparator(true);
        bestRules = new TreeSet(comparator);
        this.ctx = ctx;
    }
    public void init() {
        bestRules.clear();
    }
    private SolveBestRulesEntry freeInstance;
    public SolveBestRulesEntry getFreeInstance() {
    	if (freeInstance==null) {
    		return new SolveBestRulesEntry(ctx);
    	} else {
    		SolveBestRulesEntry tmp = freeInstance;
    		freeInstance = null;
    		ASSERT_selfConcistencyCheck(tmp);
            return tmp;
    	}
    }
    public void add(SolveBestRulesEntry br){
    	ASSERT_selfConcistencyCheck(br);
        long t1 = System.currentTimeMillis();
        bestRules.add(br);
        if (bestRules.size()>ctx.getContext().getBufferSize()) {
        	freeInstance = (SolveBestRulesEntry)bestRules.last();
        	int s1 = bestRules.size();
            bestRules.remove(freeInstance);
            int s2 = bestRules.size();
            if (s1==s2) {
            	int t =3;
            }
        }
        ASSERT_selfConcistencyCheck(freeInstance);
        long t2 = System.currentTimeMillis();
    }
    public Set getContent() {
        return bestRules;
    }
    public void ASSERT_selfConcistencyCheck(SolveBestRulesEntry currentFreeInstance) {
    	return;
//		if (currentFreeInstance!=null) {
//			Object[] objs= bestRules.toArray();
//            for (int i = 0; i < objs.length; i++) {
//				if (objs[i]==currentFreeInstance) {
//					int t =2 ;
//				}
//			}
//		}
//		ASSERT_selfConcistencyCheck();
    }
    public void ASSERT_selfConcistencyCheck() {
    	return ;
//    	if (doSelfCheck) {
//    	
//    		
//        	int mn = -1;
//    	    for (Iterator iter = bestRules.iterator(); iter.hasNext();) {
//    	        SolveBestRulesEntry bre = (SolveBestRulesEntry) iter.next();
//    	        if (mn==-1) {
//    	        	mn = bre.uncovered;
//    	        }
//    	        if (mn>bre.uncovered) {
//    	        	int t = 1;
//    	        	//break;
//    	        	//throw new RuntimeException("sort by uncovered misbehaiour");
//    	        }
//    	    }
//    	}
	}
    
    public String toString() {
        StringBuffer sb=  new StringBuffer();
        sb.append("Best Rules size="+bestRules.size());
        for (Iterator iter = bestRules.iterator(); iter.hasNext();) {
            SolveBestRulesEntry bre = (SolveBestRulesEntry) iter.next();
            sb.append(bre.toString()+"\n");
        }
        return sb.toString();
    }
    
    public String printBestRule() {
        SolveBestRulesEntry bre = (SolveBestRulesEntry) bestRules.first();
        return bre.toString();
    }
    public String printBestRuleCovering() {
    	SolveBestRulesEntry bre = (SolveBestRulesEntry) bestRules.first();
        return ""+bre.uncovered;
    }
    public SolveBestRulesEntry getBest() {
        SolveBestRulesEntry bre = (SolveBestRulesEntry) bestRules.first();
        return bre;
    }
    
}

